import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Router, navigate, Link } from 'utils/router';
import * as actions from '../actions/index';
import { Loading, Tag, Balloon, Nav } from '@teamix/ui';
import { YunxiaoIcon } from '@alife/devops-ui';
import { access } from 'components/accessContainer/util';
import MessagePage from 'components/messagePage';
import MrTitle from './components/mrTitleInfo';
import Loadable from 'utils/loadable';
import {
  postDrafts,
  updateData as updateChangeReducer,
  getCommitsRange,
  getPushRecordsDiff,
  getTotalComments,
  getDrafts,
  resetData as resetChangeData,
  commentJump,
} from 'pages/index/pages/project/pages/projectMergeRequestDetail/pages/changes/actions';
import { openCommentPanel } from 'pages/index/pages/project/pages/projectMergeRequestDetail/pages/overview/actions';
import KEYCODE from 'utils/keycode';
import { ENUM } from 'utils/constants';
import MrLeftTree from './components/leftTree';
import Read from './components/read';
import track, { Perf } from 'utils/track';
import { updatePageInfo } from 'pages/index/actions';
import Lead from 'components/Lead/index';
import utils from 'utils';
import intl from '../../../../../../../locale';

const { ctrlKey, ctrlTxt } = ENUM.getOSKeyMap();

const { pathResource } = window.FORCE;
const PROJECT_VIEW_FILE = [
  'REPORTER',
  'ORG_MEMBER',
  'DEVELOPER',
  'MASTER',
  'OWNER',
  'ORG_ADMIN',
  'ORG_OWNER',
  'ADMIN',
];

const Overview = Loadable({
  loader: () => import('../pages/overview'),
});

const Changes = Loadable({
  loader: () => import('../pages/changes'),
});

const Commits = Loadable({
  loader: () => import('../pages/commits'),
});

class Root extends Component {
  state = {
    isNavHidden: false,
    // isSidebarStick: window.TB_NAVIGATION.isSidebarStick,
    isSidebarStick: false,
    leftWidth: 300,
  };

  componentDidMount() {
    this.props.getCrDetail();
    // task:https://aone.alibaba-inc.com/issue/31474005 解决commits可能数量为0的问题
    this.props.getCrOtherInfo(() => {
      // 获取树信息
      this.props.getCommitsRange((list) => {
        this.props.receiveCommitHistory(list);
      });
    });
    // 合并请求设置接口在合并按钮以及添加评审人处用到
    this.props.getMergeRequest();
    this.props.getApproveStatus();
    this.props.getTargetBranchSetting();
    this.props.getSummaryLogs(1);
    this.props.getBuilds();
    this.props.getMrCommentConfig();
    // 切换左侧导航快捷键
    document.addEventListener('keydown', this.handleKeyCodeEvent);
    document.documentElement.classList.add('mr-html');
    setTimeout(() => {
      this.renderLeadComponent();
    }, 10000);
    // 获取白名单设置
    this.props.getIpWhiteList();
    this.mrRead = document.querySelector('.mr-read');
    const isTooLarge = utils.isTooLarge(this.props.pageInfo.pathResource);
    if (isTooLarge && document.getElementById('container')) {
      document.getElementById('container').classList.add('has-too-large-tip');
    }
    this.props.getCloneDownloadSetting();
  }

  renderMain = (curPath) => {
    return (
      <div className="mr-detail-content-view">
        {/* 111 */}
        <Router primary={false} basepath={curPath}>
          <Overview path="/" />
          <Changes path="/changes" />
          <Commits path="/commits" />
        </Router>
      </div>
    );
  };

  renderLeadComponent = () => {
    const { organization_id } = window.FORCE.organization;
    // 仅1024 活动企业展示引导
    if (organization_id !== '5f7051259cffa29cfdd39e47') {
      return;
    }

    const hasCloseGuide = utils.getCache('guide_1024', false);
    if (hasCloseGuide) {
      return;
    }

    const idName = 'mountLeadEl';
    let mountLeadEl = document.getElementById(idName);
    if (!mountLeadEl) {
      mountLeadEl = document.createElement('div');
      mountLeadEl.id = idName;
      document.body.appendChild(mountLeadEl);
    }
    // 新手引导逻辑块
    ReactDOM.render(
      <Lead
        onClose={() => {
          utils.setCache('guide_1024', true, false);
          ReactDOM.unmountComponentAtNode(document.getElementById(idName));
        }}
      />,

      document.getElementById(idName),
    );
  };

  componentDidUpdate(prevProps) {
    if (prevProps.repoSize !== this.props.repoSize) {
      const isTooLarge = utils.isTooLarge(this.props.pageInfo.pathResource);
      if (isTooLarge && document.getElementById('container')) {
        document.getElementById('container').classList.add('has-too-large-tip');
      }
    }
    if (prevProps.isStick !== this.props.isStick) {
      this.setState({
        isSidebarStick: this.props.isStick,
      });
    }
  }

  componentWillUnmount() {
    document.removeEventListener('keydown', this.handleKeyCodeEvent);
    document.removeEventListener('mousedown', this.mouseDownMoveLine);
    document.removeEventListener('mouseup', this.mouseUpMoveLine);
    document.removeEventListener('mousemove', this.handleMouseMove);
    if (this.mrNav) {
      this.mrNav.style.transform = 'translateX(0)';
    }
    if (this.mrDetailContentBody) {
      this.mrDetailContentBody.style.left = 0;
      this.mrDetailContentBody.style.width = 'auto';
    }
    if (this.mrRead && this.mrRead.style) {
      this.mrRead.style.left = 300;
    }
    this.props.resetChangeData();
    if (document.getElementById('container')) {
      document.getElementById('container').classList.remove('has-too-large-tip');
    }
    document.documentElement.classList.remove('mr-html');

    // const isStickcache = utils.getCachedData('isSidebarStick');
    // if (isStickcache === 'true' && !window.TB_NAVIGATION.isSidebarStick) {
    //   window.TB_NAVIGATION.stickSidebar();
    // }
  }

  renderStateBtn = (state) => {
    if (!state) {
      return null;
    }
    if (state === 'merged') {
      return (
        <Tag size="medium">
          <YunxiaoIcon type="merge-line" />
          {intl.get({
            id: 'code-assets.projectMergeRequestDetail.containers.root.Merged',
            defaultMessage: '已合并',
          })}
        </Tag>
      );
    }
    if (state === 'closed') {
      return (
        <Tag color="red" size="medium">
          <YunxiaoIcon type={'pull-request-closed-line'} />
          {intl.get({
            id: 'code-assets.projectMergeRequestDetail.containers.root.Disabled',
            defaultMessage: '已关闭',
          })}
        </Tag>
      );
    }
    return (
      <Tag color="green" size="medium">
        <YunxiaoIcon type="pull-request-line" />
        {intl.get({
          id: 'code-assets.projectMergeRequestDetail.containers.root.Enabled',
          defaultMessage: '已开启',
        })}
      </Tag>
    );
  };

  getKey = (curPath) => {
    const { pathname } = window.location;
    const tabTitle = pathname.replace(curPath, '');
    const titleArr = tabTitle.split('/');
    const defaultActiveKey = titleArr[titleArr.length - 1] || '/';
    return defaultActiveKey;
  };

  handleMrTabChange = (key, curPath) => {
    const { codeReviewDetail } = this.props;
    this.props.changeMrTabKey(key);
    navigate(`${curPath}${key === '/' ? '' : `/${key}`}`);
    let trackAction = '';
    if (key === '/') {
      trackAction = 'check_overview';
    } else {
      trackAction = 'check_commit_history';
    }

    track({
      action: trackAction,
      page: 'Repo-MR',
      type: '',
      control: '',
      mr_id: codeReviewDetail.id,
    });
  };

  handleToggleLeftNav = () => {
    const { isNavHidden } = this.state;
    // const fixWidth = isSidebarStick ? 280 : 104;
    if (!this.mrNav || !this.mrDetailContentBody) {
      return false;
    }
    const mrNavWidth = this.mrNav.style.width;
    let leftWidth;
    if (!this.mrRead) this.mrRead = document.querySelector('.mr-read');
    if (isNavHidden) {
      if (this.mrRead && this.mrRead.style) {
        leftWidth = mrNavWidth;
      }
      this.mrNav.style.transform = 'translateX(0)';
      this.mrDetailContentBody.style.left = mrNavWidth;
      this.mrDetailContentBody.style.width = `calc(100% - ${mrNavWidth})`;
    } else {
      if (this.mrRead && this.mrRead.style) {
        leftWidth = 0;
      }
      this.mrNav.style.transform = `translateX(-${mrNavWidth})`;
      this.mrDetailContentBody.style.left = '0px';
      this.mrDetailContentBody.style.width = '100%';
    }
    this.setState({
      isNavHidden: !isNavHidden,
      leftWidth,
    });

    this.hideNavTrack(!isNavHidden);
  };

  handleKeyCodeEvent = (e) => {
    const { codeReviewDetail } = this.props;
    // ctrl + B 展开、收起左侧树
    const { isNavHidden } = this.state;
    if (e[ctrlKey] && e.keyCode === KEYCODE.B) {
      if (!this.mrNav || !this.mrDetailContentBody) {
        return false;
      }
      const mrNavWidth = this.mrNav.style.width;
      let leftWidth;
      if (!this.mrRead) this.mrRead = document.querySelector('.mr-read');
      if (isNavHidden) {
        if (this.mrRead && this.mrRead.style) {
          leftWidth = mrNavWidth;
        }
        this.mrNav.style.transform = 'translateX(0)';
        this.mrDetailContentBody.style.left = mrNavWidth;
        this.mrDetailContentBody.style.width = `calc(100% - ${mrNavWidth})`;
      } else {
        if (this.mrRead && this.mrRead.style) {
          leftWidth = 0;
        }
        this.mrNav.style.transform = `translateX(-${mrNavWidth})`;
        this.mrDetailContentBody.style.left = '0px';
        this.mrDetailContentBody.style.width = '100%';
      }
      this.setState({
        isNavHidden: !isNavHidden,
        leftWidth,
      });

      this.hideNavTrack(!isNavHidden);
      track({
        action: 'set_sidebar',
        page: '',
        type: 'shortcuts',
        control: '',
        mr_id: codeReviewDetail.id,
      });
    }
  };

  hideNavTrack = (isNavHidden) => {
    const { codeReviewDetail } = this.props;
    track({
      action: isNavHidden ? 'hide_sidebar' : 'show_sidebar',
      page: 'Repo-MR',
      type: '',
      control: '',
      mr_id: codeReviewDetail.id,
    });
  };

  renderBody = () => {
    const { codeReviewDetail, commitHistory, mrTabKey } = this.props;
    const curPath = `/${pathResource.fullPath}/merge_request/${codeReviewDetail.id}`;
    const { isNavHidden, isSidebarStick, leftWidth = 300 } = this.state;
    const fixWidth = isSidebarStick ? 220 : 64;
    const mrReadLeft = isNavHidden ? `${fixWidth}px` : `${parseInt(leftWidth) + fixWidth}px`;
    const curTabKey = mrTabKey || this.getKey(curPath);
    const commitsCount = commitHistory ? commitHistory.length : 0;
    const selectedKey = curTabKey === 'overview' ? '/' : curTabKey;
    const isTooLarge = utils.isTooLarge(this.props.pageInfo.pathResource);

    return (
      <div
        ref={(r) => {
          this.mrDetailContentBody = r;
        }}
        className={`mr-detail-content-body ${isNavHidden ? 'no-nav' : ''}`}
        id="mr-content-body"
        style={{ width: 'calc(100% - 300px)' }}
      >
        <>
          <Balloon.Tooltip
            align="r"
            trigger={
              <div
                className={`mr-hide-fix-icon ${isNavHidden ? 'flex' : 'hide'}`}
                style={{ left: `${fixWidth - 1}px` }}
                onClick={this.handleToggleLeftNav}
              >
                <YunxiaoIcon type="right-forward-line" />
              </div>
            }
          >
            {intl.get({
              id: 'code-assets.projectMergeRequestDetail.containers.root.Expand',
              defaultMessage: '展开',
            })}
            <br />
            {ctrlTxt} + B
          </Balloon.Tooltip>
          <div className="mr-nav-fix-hide" style={{ width: `${fixWidth}px` }} />
          <div
            className="mr-nav"
            style={{ width: '300px', left: `${fixWidth}px` }}
            ref={(r) => {
              this.mrNav = r;
            }}
          >
            <div className="mr-nav-move-line" onMouseDown={this.mouseDownMoveLine}>
              <div />
            </div>
            {isNavHidden ? null : (
              <Balloon.Tooltip
                align="r"
                trigger={
                  <div className="mr-nav-fix-icon" onClick={this.handleToggleLeftNav}>
                    <YunxiaoIcon type="left-backward-line" size="small" />
                  </div>
                }
              >
                {intl.get({
                  id: 'code-assets.projectMergeRequestDetail.containers.root.PutAway',
                  defaultMessage: '收起',
                })}
                <br />
                {ctrlTxt} + B
              </Balloon.Tooltip>
            )}
            {/* <div className="mr-nav-line" /> */}
            <div className="mr-nav-tree">
              <div className="mr-tab-list">
                <Nav selectedKeys={[selectedKey]} type="normal" direction="ver">
                  <Nav.Item key="/">
                    <Link
                      to={curPath}
                      onClick={() => {
                        this.handleMrTabChange('/', curPath);
                      }}
                    >
                      {intl.get({
                        id: 'code-assets.projectMergeRequestDetail.containers.root.GlobalOverview',
                        defaultMessage: '全局概览',
                      })}
                    </Link>
                  </Nav.Item>
                  <Nav.Item key="commits">
                    <Link
                      to={`${curPath}/commits`}
                      onClick={() => {
                        this.handleMrTabChange('commits', curPath);
                      }}
                      style={{ display: 'block' }}
                    >
                      <div>
                        {intl.get({
                          id: 'code-assets.projectMergeRequestDetail.containers.root.SubmissionHistory',
                          defaultMessage: '提交历史',
                        })}
                        <span className="badge-count">{commitsCount}</span>
                      </div>
                    </Link>
                  </Nav.Item>
                </Nav>
              </div>

              <div>
                <MrLeftTree
                  {...this.props.changesReducer}
                  projectMergeRequestDetailRoot={this.props.codeReviewDetail}
                  getDrafts={this.props.getDrafts}
                  getTotalComments={this.props.getTotalComments}
                  getPushRecordsDiff={this.props.getPushRecordsDiff}
                  updateData={this.props.updateChangeReducer}
                  changeMrTabKey={this.props.changeMrTabKey}
                  mrTabKey={this.props.mrTabKey}
                  // mr评论优化
                  openCommentPanel={this.props.openCommentPanel}
                  commentJump={this.props.commentJump}
                  fixWidth={fixWidth}
                  // clone button
                  project_clone_download={this.props.project_clone_download}
                  ipSetting={this.props.ipSetting}
                />
              </div>
            </div>
          </div>
        </>
        <div className="mr-detail-content-body-right">
          <Read
            isNavHidden={isNavHidden}
            {...this.props.changesReducer}
            getDrafts={this.props.getDrafts}
            getTotalComments={this.props.getTotalComments}
            getPushRecordsDiff={this.props.getPushRecordsDiff}
            updateData={this.props.updateChangeReducer}
            changeMrTabKey={this.props.changeMrTabKey}
            mrTabKey={this.props.mrTabKey}
            isTooLarge={isTooLarge}
            fixWidth={fixWidth}
            leftWidth={mrReadLeft}
          />

          {this.renderMain(curPath)}
        </div>
      </div>
    );
  };

  mouseDownMoveLine = () => {
    if (!this.mrNav) return false;
    if (!this.mrRead) this.mrRead = document.querySelector('.mr-read');
    this.mrNav.style.transition = 'unset';
    document.addEventListener('mousemove', this.handleMouseMove);
    document.addEventListener('mouseup', this.mouseUpMoveLine);
  };

  mouseUpMoveLine = () => {
    if (!this.mrNav) return false;
    this.mrNav.style.transition = 'ease-in 300ms';
    document.removeEventListener('mouseup', this.mouseUpMoveLine);
    document.removeEventListener('mousemove', this.handleMouseMove);
    this.setState({
      leftWidth: parseInt(this.mrDetailContentBody.style.left, 10),
    });
  };

  handleMouseMove = (e) => {
    e.preventDefault();
    e.stopPropagation();
    if (!this.mrNav || !this.mrDetailContentBody) return false;
    let { pageX } = e;
    // 左侧最小宽度247px
    const { isSidebarStick } = this.state;
    const fixWidth = isSidebarStick ? 220 : 64;
    if (pageX - fixWidth < 247) {
      pageX = fixWidth + 247;
    }
    if (pageX - fixWidth > 647) {
      pageX = fixWidth + 647;
    }
    this.mrNav.style.width = `${pageX - fixWidth}px`;
    this.mrDetailContentBody.style.left = `${pageX - fixWidth}px`;
    this.mrDetailContentBody.style.width = `calc(100% - ${pageX - fixWidth}px)`;
    if (this.mrRead && this.mrRead.style) {
      this.mrRead.style.left = `${pageX}px`;
    }
    return false;
  };

  render() {
    const { isLoadingDetail } = this.props;
    const { role } = pathResource;
    const hasViewFileAuth = access(PROJECT_VIEW_FILE, role);
    return (
      <>
        {hasViewFileAuth ? (
          <div className="mr-detail-container">
            {!isLoadingDetail ? (
              <div className="mr-detail-content">
                <div className="mr-detail-content-header">
                  <MrTitle {...this.props} />
                </div>
                {this.renderBody()}
                <Perf page={'Repo-MR'} />
              </div>
            ) : (
              <div className="mr-detail-loading">
                <Loading />
              </div>
            )}
          </div>
        ) : (
          <MessagePage
            pictureUrl="https://img.alicdn.com/tfs/TB14JNzD1uSBuNjy1XcXXcYjFXa-700-700.png"
            title={intl.get({
              id: 'code-assets.projectMergeRequestDetail.containers.root.NoAccessPermission',
              defaultMessage: '无访问权限',
            })}
            desc={intl.get({
              id: 'code-assets.projectMergeRequestDetail.containers.root.ContactTheDatabaseAdministratorTo',
              defaultMessage: '请联系库管理员进行添加',
            })}
          />
        )}
      </>
    );
  }
}

export default connect(
  (state) => {
    return {
      ...state.project.projectMergeRequestDetail.root,
      changesReducer: state.project.projectMergeRequestDetail.changesReducer,
      rootState: state.root,
      pageInfo: state.root.pageInfo,
      lastMirrorSyncRecord: state.project.root.lastMirrorSyncRecord,
    };
  },
  (dispatch) =>
    bindActionCreators(
      {
        ...actions,
        postDrafts,
        getDrafts,
        getCommitsRange,
        updateChangeReducer,
        getPushRecordsDiff,
        getTotalComments,
        resetChangeData,
        updatePageInfo,
        openCommentPanel,
        commentJump,
      },
      dispatch,
    ),
)(Root);
